package com.jishuo.base.service;

import com.github.pagehelper.PageHelper;
import com.jishuo.base.bean.BaseResult;
import com.jishuo.base.bean.ErrorCodeEnum;
import com.jishuo.base.bean.Pagination;
import com.jishuo.base.bean.vo.RoleVO;
import com.jishuo.base.bean.vo.UserVO;
import com.jishuo.base.config.AppConfig;
import com.jishuo.base.dao.UserMapper;
import com.jishuo.base.util.MD5;
import com.jishuo.base.util.SaltedPasswordUtil;
import com.jishuo.base.util.StringUtil;
import com.jishuo.nontax.bean.vo.BankStationVO;
import com.jishuo.nontax.bfc.dao.BaseDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户管理
 */
@Slf4j
@Service
public class UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private BaseDataMapper baseDataMapper;

    @Resource
    private RoleService roleService;

    @Resource
    private MenuService menuService;

    @Value("${user.init-pwd}")
    private String initPwd;

    /**
     * 检测复核用户
     * @param userCode 编码
     * @param pwd 密码
     * @return
     */
    public BaseResult chkAuthUser(String userCode, String pwd, UserVO luser) {
        if (luser.getUserCode().equals(userCode)) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "复核用户不能与操作用户相同");
        UserVO user = this.userMapper.getUserByCode(userCode);
        if (user == null) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户不存在");
        if (user.getState() != 1) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户不可用");
        boolean isSm3 = user.getUserPwd().indexOf("&&") > 1;
        boolean pwdOk = (isSm3) ? SaltedPasswordUtil.checkPwd(pwd, user.getUserPwd()) : MD5.md5s(pwd).equals(user.getUserPwd());
        if (!pwdOk) return BaseResult.CustomErr("复核用户验证失败");
        return new BaseResult();
    }

    /**
     * 登录
     * @param userCode 用户编码
     * @param pwd 登录密码
     * @return
     */
    public BaseResult login(String userCode, String pwd) {
        UserVO user = this.userMapper.getUserByCode(userCode);
        if (user == null) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户不存在");
        if (user.getState() != 1) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户不可用");
        // 验证密码
        boolean isSm3 = user.getUserPwd().indexOf("&&") > 1;
        boolean pwdOk = (isSm3) ? SaltedPasswordUtil.checkPwd(pwd, user.getUserPwd()) : MD5.md5s(pwd).equals(user.getUserPwd());
        if (!pwdOk) return BaseResult.CustomErr("登录失败");

        // 初始密码登录，强制更改密码
//        if (pwd.equals(initPwd)) return new BaseResult(AppConfig.CUSTOM_ERR, "初始密码登录，请先更换密码");
        // 设置菜单
        if (StringUtil.isEmpty(user.getMenuId())) {
            // 取角色菜单
            user.setMenuId(this.roleService.getMenuIds(user.getRole()));
        } else {
            user.setMenuId("," + user.getMenuId() + ",");
        }
        // 设置菜单url权限
        menuService.setUserMenu(user);

        BankStationVO station = baseDataMapper.getBankStation(user.getBankStationId());
        if (station != null) {
            user.setBankStationCode(station.getBankstationcode());
            user.setBankStationName(station.getBankstationname());
        }

        if (!isSm3) {
            // 更新为sm3加密
            String sm3Pwd = SaltedPasswordUtil.encode(pwd);
            this.userMapper.resetUserPwd(user.getUserId(), sm3Pwd);
        }
        user.setUserPwd("******");

        return new BaseResult(user);
    }

    /**
     * 用户列表，分页
     * @param user 查询条件，state，usercode，cantonid
     * @param pagination
     * @return
     */
    public List<UserVO> listUser(UserVO user, Pagination pagination) {
        if (pagination.getRows() > 0) PageHelper.startPage(pagination.getPage(), pagination.getRows());
        List<UserVO> userVOS = this.userMapper.listUser(user);
        List<RoleVO> roleList = this.roleService.listRole(new RoleVO(), null);
        for (UserVO userVO : userVOS) {
            userVO.setUserPwd("******");
            if (StringUtil.isNotEmpty(userVO.getRole())) {
                String roleIds = "," + userVO.getRole() + ",";
                String rolename = "";
                for (RoleVO roleVO : roleList) {
                    if (roleIds.contains("," + roleVO.getRoleId() + ",")) {
                        rolename += "," + roleVO.getRoleName();
                    }
                }
                if (rolename.length() > 0) rolename = rolename.substring(1);
                userVO.setRoleName(rolename);
            }
        }
        return userVOS;
    }

    /** 获取用户，主键 */
    public UserVO getUser(long userId) {
        return this.userMapper.getUser(userId);
    }

    /** 获取用户，用户编号 */
    public UserVO getUserByCode(String userCode) {
        return this.userMapper.getUserByCode(userCode);
    }

    /** 新增用户 */
    public BaseResult addUser(UserVO user) {
        try {
            UserVO vo = this.userMapper.getUserByCode(user.getUserCode());
            if (vo != null){
                return new BaseResult(AppConfig.CUSTOM_ERR, "用户编号已存在");
            }
            // 设置用户ID
            user.setUserPwd(SaltedPasswordUtil.encode(user.getUserPwd()));
            user.setState(1);
            return (this.userMapper.addUser(user) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    /** 更新用户 */
    public BaseResult saveUser(UserVO user) {
        try {
            if(user.getUserPwd().equals("******")){
                user.setUserPwd(null);
            }else{
                user.setUserPwd(SaltedPasswordUtil.encode(user.getUserPwd()));
            }
            return (this.userMapper.saveUser(user) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    public BaseResult editMenuUser(UserVO user) {
        try {
            return (this.userMapper.editMenuUserId(user) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    public BaseResult editBankUserId(UserVO user) {
        try {
            return (this.userMapper.editBankUserId(user) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    /** 删除用户 */
    public BaseResult deleteUser(long userId) {
        try {
            return (this.userMapper.deleteUser(userId) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    /** 重置密码 */
    public BaseResult resetUserPwd(long userId) {
        String sm3Pwd = SaltedPasswordUtil.encode(initPwd);
        try {
            return (this.userMapper.resetUserPwd(userId, sm3Pwd) > 0) ? new BaseResult() : new BaseResult(ErrorCodeEnum.DB_ERR);
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.DB_ERR);
        }
    }

    /** 修改密码 */
    public BaseResult editUserPwd(UserVO userVO,String oldPassword,String newPassword) {
        UserVO user = this.userMapper.getUserByCode(userVO.getUserCode());

        boolean isSm3 = user.getUserPwd().indexOf("&&") > 1;
        boolean pwdOk = (isSm3) ? SaltedPasswordUtil.checkPwd(oldPassword, user.getUserPwd()) : MD5.md5s(oldPassword).equals(user.getUserPwd());
        if (!pwdOk) return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "原密码不正确");

        String sm3Pwd = SaltedPasswordUtil.encode(newPassword);
        if (userMapper.resetUserPwd(user.getUserId(), sm3Pwd) > 0) return new BaseResult();
        return new BaseResult(ErrorCodeEnum.DB_ERR.getCode(),"请刷新页面重试");
    }

    /** 网点类别 */
    public List<BankStationVO> listBankStation() {
        return this.userMapper.listBankStation(null);
    }

    public int isFHUser(String usercode,String userpwd){
        userpwd = new MD5().md5s(userpwd.trim());
        return userMapper.getUserCount(userpwd,usercode);
    }
}
